#include "PolyLineView.h"

namespace poly
{
	const DWORD PolyLineView::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;
	const uint32 PolyLineView::vertexSize = sizeof(float3) + sizeof(DWORD);

	PolyLineView::PolyLineView(poly::D3DDevice device) :
		m_color( 1.f, 0.f, 0.f, 0.f )
	{
		initialize( device );
		m_vertexBuffer = 0;
	}

	void PolyLineView::initialize( D3DDevice device )
	{
		m_device = device;
		m_vertexBuffer = 0;
	}

	PolyLineView::~PolyLineView()
	{
		destroy();
	}

	void PolyLineView::destroy()
	{
		m_device = 0;
		m_polyLine.clear();
		SAFE_RELEASE( m_vertexBuffer );
	}

	void PolyLineView::setPolyLine( PolyLine const & P )
	{
		m_polyLine = P;
	}

	void PolyLineView::setColor( float4 const & color )
	{
		m_color = color;
	}

	float4 PolyLineView::color() const
	{
		return m_color;
	}

	void PolyLineView::setup( PolyLine const & P, float4 const & diffuse )
	{
		setPolyLine( P );
		setColor( diffuse );

		SAFE_RELEASE( m_vertexBuffer );
		if( m_device != 0 )
		{
			uint32 byteLength = vertexSize * m_polyLine.size();
			if( byteLength == 0 ) return;
			m_device->CreateVertexBuffer(
				byteLength,
				0, // usage
				FVF,
				D3DPOOL_MANAGED,
				&m_vertexBuffer,
				0 );

			uint8 * data;
			m_vertexBuffer->Lock( 0, 0, (void**)& data, 0 );

			D3DCOLOR diffuse = D3DCOLOR_ARGB(
				(uint32)(m_color.x * 255),
				(uint32)(m_color.y * 255),
				(uint32)(m_color.z * 255),
				(uint32)(m_color.w * 255) );

			for( size_t i = 0; i < m_polyLine.size(); i++ )
			{
				memcpy( data, &(m_polyLine[i]), sizeof(float3) );
				data += sizeof(float3);
				memcpy( data, &(diffuse), sizeof(D3DCOLOR) );
				data += sizeof(D3DCOLOR);
			}
			m_vertexBuffer->Unlock();
		}
	}

	void PolyLineView::render( float44 const & world )
	{
		if( m_vertexBuffer == 0 )
			return;

		m_device->SetTransform( D3DTS_WORLD, &world );
		m_device->SetStreamSource( 0, m_vertexBuffer, 0, vertexSize );
		m_device->SetFVF( FVF );
		m_device->SetRenderState( D3DRS_LIGHTING, FALSE );

		m_device->DrawPrimitive( D3DPT_LINESTRIP, 0, (int)(m_polyLine.size()-1) );
	}
}
